JasmineJS তে Mocking এবং Stubbing হলো টেস্টিং প্রক্রিয়ায় ব্যবহৃত দুটি গুরুত্বপূর্ণ কৌশল। এগুলি প্রধানত ডিপেন্ডেন্সি টেস্টিংয়ের জন্য ব্যবহৃত হয়, যেখানে আপনি কোন নির্দিষ্ট ফাংশন বা মেথডের আচরণ পরিবর্তন করে বা সিমুলেট করে টেস্ট করতে পারেন।
Mocking কি?
Mocking হলো একটি কৌশল, যেখানে আপনি একটি ফাংশন বা অবজেক্টের আচরণ কৃত্রিমভাবে নিয়ন্ত্রণ করতে পারেন, যাতে টেস্টের সময় কোনো বাহ্যিক ডিপেন্ডেন্সি বা আচরণকে এড়িয়ে চলে। Mocking এর মাধ্যমে আপনি একটি মক অবজেক্ট তৈরি করতে পারেন যা টেস্টের মধ্যে প্রত্যাশিত কার্যকারিতা প্রদান করে।
Mocking এর উপকারিতা:
- বাহ্যিক সার্ভিস বা অবজেক্টের আচরণকে সিমুলেট করা।
- টেস্টের সময় সঠিক আউটপুট নিশ্চিত করা।
- সিস্টেমের নির্দিষ্ট অংশের আচরণ পরীক্ষা করা।
Stubbing কি?
Stubbing হলো এক ধরনের Mocking, যেখানে আপনি নির্দিষ্ট ফাংশন বা মেথডকে এমনভাবে সিমুলেট করেন যাতে তার পূর্বনির্ধারিত আউটপুট প্রদান করে। এটি সাধারণত যখন আপনি কোন ফাংশন বা মেথডের বাস্তব আচরণ জানেন না, তখন তার একটি কৃত্রিম (stub) ভার্সন ব্যবহার করেন।
Stubbing এর উপকারিতা:
- একটি নির্দিষ্ট ফাংশনের আউটপুট পূর্বনির্ধারণ করা।
- অবজেক্টের যেসব অংশ পরিবর্তনশীল, সেগুলিকে সঠিকভাবে সিমুলেট করা।
JasmineJS এ Mocking এবং Stubbing
JasmineJS এ spyOn() ফাংশনটি প্রধানত mocking এবং stubbing এর জন্য ব্যবহৃত হয়। এটি মূলত একটি ফাংশন বা মেথডের আচরণ পরীক্ষা বা সিমুলেট করতে সাহায্য করে।
1. spyOn() এর মাধ্যমে Mocking
spyOn() ব্যবহৃত হয় একটি মেথডকে ট্র্যাক বা মক (mock) করার জন্য। এর মাধ্যমে আপনি মেথডটির কনট্রোল নিতে পারেন এবং পরীক্ষার জন্য তাকে সঠিক আউটপুট ফিরিয়ে দিতে পারেন।
উদাহরণ:
describe("Mocking with spyOn", function() {
it("should mock the add function", function() {
const obj = {
add: function(a, b) {
return a + b;
}
};
spyOn(obj, "add").and.returnValue(10); // add মেথডটিকে মক করা এবং ১০ রিটার্ন করা
expect(obj.add(2, 3)).toBe(10); // টেস্ট হবে যে, add ফাংশনটি ১০ রিটার্ন করছে কিনা
});
});
এখানে:
spyOn(obj, "add"):objঅবজেক্টেরaddমেথডটি স্পাই করা হয়েছে।and.returnValue(10):addমেথডটি যে ১০ রিটার্ন করবে, সেটা নির্ধারণ করা হয়েছে।
2. spyOn() এর মাধ্যমে Stubbing
Stubbing এর জন্যও spyOn() ব্যবহার করা হয়। আপনি and.callFake() এর মাধ্যমে ফাংশনের আচরণ পরিবর্তন করে একটি কৃত্রিম আউটপুট প্রদান করতে পারেন।
উদাহরণ:
describe("Stubbing with spyOn", function() {
it("should stub the add function to return fixed value", function() {
const obj = {
add: function(a, b) {
return a + b;
}
};
spyOn(obj, "add").and.callFake(function(a, b) {
return a * b; // add ফাংশনের আচরণ পরিবর্তন করে, গুণফল রিটার্ন করা
});
expect(obj.add(2, 3)).toBe(6); // এখানে ১০ নয়, ২ এবং ৩ এর গুণফল ৬ আসবে
});
});
এখানে:
and.callFake(): এটি ব্যবহার করে আপনি ফাংশনের আচরণ পরিবর্তন করেছেন। পূর্বেaddফাংশনটি যোগফল (sum) ফেরত দিত, তবে এখানে সেটি গুণফল (product) ফিরিয়ে দিচ্ছে।
3. spyOn() এর মাধ্যমে কল ট্র্যাকিং
Jasmine এর spyOn() শুধু মেথডের আচরণ পরিবর্তন করে না, এটি কল ট্র্যাক করতে (কতবার কল হয়েছে, কি আর্গুমেন্ট পাস হয়েছে) সাহায্যও করে।
উদাহরণ:
describe("Tracking function calls with spyOn", function() {
it("should track the calls to the add function", function() {
const obj = {
add: function(a, b) {
return a + b;
}
};
spyOn(obj, "add"); // add মেথডটিকে স্পাই করা
obj.add(2, 3);
obj.add(4, 5);
expect(obj.add).toHaveBeenCalled(); // পরীক্ষা করবে যে, add মেথডটি কল হয়েছে কিনা
expect(obj.add).toHaveBeenCalledTimes(2); // add মেথডটি ২ বার কল হয়েছে
expect(obj.add).toHaveBeenCalledWith(2, 3); // add মেথডটি ২ এবং ৩ প্যারামিটার সহ কল হয়েছে
});
});
এখানে:
toHaveBeenCalled(): পরীক্ষা করবে যে ফাংশনটি কল হয়েছে কিনা।toHaveBeenCalledTimes(): পরীক্ষা করবে ফাংশনটি কয়বার কল হয়েছে।toHaveBeenCalledWith(): পরীক্ষা করবে যে ফাংশনটি নির্দিষ্ট আর্গুমেন্ট দিয়ে কল হয়েছে কিনা।
4. and.throwError() এর মাধ্যমে Error Throwing
যখন আপনি কোন ফাংশনে error throwing ট্র্যাক করতে চান, তখন and.throwError() ব্যবহার করা হয়। এটি কোনো error বা exception সিমুলেট করতে সাহায্য করে।
উদাহরণ:
describe("Throwing error with spyOn", function() {
it("should throw an error", function() {
const obj = {
divide: function(a, b) {
if (b === 0) {
throw new Error("Division by zero");
}
return a / b;
}
};
spyOn(obj, "divide").and.throwError("Division by zero");
expect(function() { obj.divide(2, 0); }).toThrowError("Division by zero");
});
});
এখানে:
and.throwError():divideমেথডের মধ্যে error সিমুলেট করা হয়েছে। যখন এটি ০ দিয়ে ভাগ করতে যাবে, তখন "Division by zero" ত্রুটি (error) ছুঁড়ে দিবে।
সারাংশ
Mocking এবং Stubbing JasmineJS এ অত্যন্ত গুরুত্বপূর্ণ টেকনিক্যাল কৌশল যা টেস্টিংকে আরও নমনীয় ও কার্যকর করে তোলে। spyOn() ফাংশনের মাধ্যমে আপনি মেথডের আচরণ পরিবর্তন করতে পারেন, তাকে মক বা স্টাব করতে পারেন, কল ট্র্যাক করতে পারেন এবং error সিমুলেট করতে পারেন। এর ফলে, আপনি কোডের নির্দিষ্ট অংশের আচরণ পরীক্ষা করতে পারেন, যা আপনার টেস্টিং প্রক্রিয়াকে আরও নির্ভুল এবং শক্তিশালী করে তোলে।
Mocking হল টেস্টিং এর একটি গুরুত্বপূর্ণ কৌশল যা পরীক্ষার সময় নির্দিষ্ট অংশগুলোর আচরণ নকল (simulate) করার জন্য ব্যবহৃত হয়। JasmineJS এ mocking ব্যবহৃত হয় মূলত সিস্টেম বা অ্যাপ্লিকেশনের বিভিন্ন বাইরের সিস্টেম বা ডিপেনডেন্সি যেমন API কল, ডাটাবেজ অপারেশন, থার্ড-পার্টি লাইব্রেরি, ইত্যাদি পরীক্ষার জন্য। এর মাধ্যমে আপনি নির্দিষ্ট অংশগুলোর আচরণ নির্ধারণ করতে পারেন, যা মূল কোডের কার্যকারিতা বা আচরণকে প্রভাবিত না করে নির্দিষ্ট লজিক পরীক্ষা করার সুযোগ দেয়।
Mocking টেস্টিং এর সময় অপরিহার্য কারণ এটি কোডের নির্ভরশীলতাগুলোর পরিবর্তে আপনার টেস্ট কেসগুলোকে এক্সিকিউট করতে সহায়তা করে। এর মাধ্যমে টেস্টগুলো দ্রুত, নির্ভরযোগ্য এবং পুনরাবৃত্তি যোগ্য হয়ে ওঠে।
Mocking এর ভূমিকা
Mocking এর মাধ্যমে আপনি এমন ডিপেনডেন্সি গুলি ব্যবহার করতে পারেন, যা প্রকৃতপক্ষে পুরো সিস্টেমের সাথে যুক্ত নয়, তবে টেস্ট করার জন্য গুরুত্বপূর্ণ। এটি মূলত দুটি উদ্দেশ্যে ব্যবহৃত হয়:
- ডিপেনডেন্সি আইসোলেশন (Dependency Isolation): আপনার টেস্ট শুধুমাত্র একটি নির্দিষ্ট ইউনিট বা ফাংশনকে পরীক্ষা করবে, অন্য কোনো বাহ্যিক ফ্যাক্টরের প্রভাব ছাড়া।
- পারফরম্যান্স উন্নয়ন (Performance Improvement): বাইরের সিস্টেম বা ডিপেনডেন্সির সাথে বাস্তব যোগাযোগ করার চেয়ে নকল (mock) ব্যবহার করলে টেস্ট দ্রুত চলে।
উদাহরণ:
ধরা যাক, আপনি একটি ফাংশন পরীক্ষা করতে চান যা একটি API থেকে ডেটা নিয়ে কাজ করে। কিন্তু API কলটি বাস্তবায়ন করতে সময় নিতে পারে বা আপনার টেস্ট পরিবেশে সেটি অ্যাক্সেসযোগ্য নাও হতে পারে। এ ক্ষেত্রে আপনি API কলটি মক (mock) করতে পারেন।
Mocking এর প্রয়োজনীয়তা
বাইরের নির্ভরশীলতা (External Dependencies)
প্রায়ই কোডের কিছু অংশ বাইরের সিস্টেমের উপর নির্ভর করে থাকে, যেমন:
- API কল
- ডাটাবেজ ইন্টারঅ্যাকশন
- ফাইল সিস্টেম অপারেশন
- থার্ড-পার্টি লাইব্রেরি ইত্যাদি
যখন আপনি টেস্ট করেন, তখন এগুলোর আচরণ আপনার টেস্টের ফলাফলে প্রভাব ফেলতে পারে। এগুলোর মধ্যে কোনো সমস্যা থাকলে আপনার টেস্টও ব্যর্থ হতে পারে, যেটি আসলে আপনার কোডের সমস্যা নয়।
Mocking এর মাধ্যমে আপনি এই বাইরের নির্ভরশীলতাগুলোর আচরণ "নকল" করতে পারেন, যাতে আপনার টেস্টটি কেবলমাত্র আপনি পরীক্ষা করতে চাওয়া কোডের অংশের উপর নির্ভরশীল থাকে।
উদাহরণ:
ধরা যাক, আপনি একটি ফাংশন পরীক্ষা করতে চান যা ডাটাবেজ থেকে ডেটা পড়বে এবং সেই ডেটা প্রক্রিয়া করবে। কিন্তু ডাটাবেজ অ্যাক্সেস করা খুবই ধীরগতির এবং আপনার টেস্ট পরিবেশে ডাটাবেজ না থাকায়, এই অংশটি নকল করা প্রয়োজন।
describe("Database Interaction", function() {
it("should return the correct user data", function() {
const mockDatabase = {
getUser: function(id) {
return { id: id, name: "John Doe" }; // মক ডাটাবেজ
}
};
const user = mockDatabase.getUser(1);
expect(user.name).toBe("John Doe"); // টেস্টের জন্য মক ডাটাবেজ ব্যবহার
});
});
এখানে, ডাটাবেজের সাথে প্রকৃত যোগাযোগ না করেই আপনি ডাটাবেজের getUser ফাংশনটির আচরণ পরীক্ষা করতে পারছেন।
JasmineJS এ Mocking এর ব্যবহার
JasmineJS এ Mocking করার জন্য কিছু গুরুত্বপূর্ণ ফাংশন এবং কৌশল রয়েছে:
1. Spies (স্পাইস)
JasmineJS এ স্পাইস (spies) ব্যবহার করা হয় মকিংয়ের জন্য। স্পাইস হল এমন ফাংশন যা ফাংশন বা মেথডের আচরণ ট্র্যাক করে, যেমন কবে ফাংশনটি কল হয়েছে, কতবার কল হয়েছে, কোন আর্গুমেন্ট সহ কল হয়েছে এবং রিটার্ন মান কী ছিল।
ব্যবহার:
describe("Spy Example", function() {
it("should call the function once", function() {
const spy = jasmine.createSpy("myFunction");
spy(); // ফাংশনটি কল করা হলো
expect(spy).toHaveBeenCalled(); // স্পাই চেক করবে যে ফাংশনটি কল হয়েছে
expect(spy).toHaveBeenCalledTimes(1); // একবার কল হয়েছে
});
});
এখানে createSpy() ফাংশনটি একটি স্পাই তৈরি করে, যা পরবর্তীতে পরীক্ষা করতে পারে আপনি কতবার এবং কোন আর্গুমেন্ট সহ ফাংশনটি কল করেছেন।
2. Mock Functions (মক ফাংশন)
JasmineJS এ আপনি মক ফাংশন ব্যবহার করে বাহ্যিক ফাংশন বা মেথডের আচরণ নকল করতে পারেন। আপনি এটি করতে পারেন jasmine.createSpy() ব্যবহার করে।
ব্যবহার:
describe("Mock Function Example", function() {
it("should mock an API call", function() {
const mockApiCall = jasmine.createSpy().and.returnValue(Promise.resolve("data"));
mockApiCall().then(response => {
expect(response).toBe("data"); // মক API কলের রিটার্ন ভ্যালু পরীক্ষা
});
});
});
এখানে, mockApiCall() একটি মক ফাংশন যা একটি প্রমিস রিটার্ন করে, যা আপনি পরীক্ষা করতে পারবেন।
3. Stub Functions (স্টাব ফাংশন)
স্টাব হল একটি বিশেষ ধরনের মক ফাংশন যা নির্দিষ্ট আউটপুট রিটার্ন করে এবং মেথড কলের আচরণ পরিবর্তন করতে পারে।
ব্যবহার:
describe("Stub Example", function() {
it("should stub a method to return a specific value", function() {
const object = {
fetchData: function() {
return "real data"; // বাস্তব ডেটা
}
};
spyOn(object, 'fetchData').and.returnValue("stubbed data"); // স্টাব করা
expect(object.fetchData()).toBe("stubbed data"); // স্টাবbed ডেটা পরীক্ষা
});
});
এখানে fetchData মেথডটি স্টাব করা হয়েছে, যার ফলে এটি "real data" না দিয়ে "stubbed data" রিটার্ন করবে।
সারাংশ
Mocking এর মাধ্যমে আপনি বাইরের ডিপেনডেন্সি ও সিস্টেমকে নকল (simulate) করতে পারেন, যাতে আপনার টেস্ট শুধু আপনার কোডের লজিকের উপর নির্ভর করে। JasmineJS এ স্পাই, মক ফাংশন এবং স্টাব ফাংশন ব্যবহার করে আপনি টেস্টিংয়ের সময় কোডের নির্ভরশীলতা নির্ধারণ করতে পারবেন, যার ফলে টেস্টগুলো আরও দ্রুত, নির্ভরযোগ্য এবং আইসোলেটেড (isolated) হবে।
Mocking এর মাধ্যমে আপনি:
- বাইরের সিস্টেমের প্রভাব থেকে আপনার কোডকে আলাদা করতে পারেন।
- কোডের বিভিন্ন অংশের নির্ভরশীলতাগুলো নিয়ন্ত্রণ করতে পারেন।
- টেস্টের পারফরম্যান্স উন্নত করতে পারেন।
JasmineJS এর মকিং টুলস এবং কৌশলগুলো অ্যাসিঙ্ক্রোনাস কাজের জন্যও খুবই উপযোগী এবং এটা টেস্টিংয়ের কার্যকারিতা উন্নত করতে সহায়তা করে।
JasmineJS এ Mocks তৈরি করার মাধ্যমে আপনি টেস্টিং এর সময় নির্দিষ্ট ফাংশন বা মেথডগুলির আচরণ সিমুলেট করতে পারেন, যাতে আসল কার্যকারিতা কল না হয়। এটি unit testing এর একটি গুরুত্বপূর্ণ অংশ, যেখানে আপনি নির্দিষ্ট কম্পোনেন্টের নির্ভরশীলতা (dependencies) কাটিয়ে টেস্ট করার জন্য মক অবজেক্ট বা ফাংশন ব্যবহার করেন।
Mocking এর মাধ্যমে আপনি একটি নির্দিষ্ট ফাংশন বা মেথডের return value, call count, parameters ইত্যাদি পরীক্ষা করতে পারেন, যা বিশেষ করে external APIs বা ডাটাবেস কলের জন্য উপকারী।
JasmineJS এ Mocking এর ধারণা
JasmineJS মকিং এর জন্য spyOn() ফাংশন ব্যবহার করে থাকে। spyOn() মক ফাংশন বা মেথড তৈরি করে, যা আসল ফাংশনের আচরণ সিমুলেট করতে পারে। এটি ফাংশনের কল রেকর্ড করে এবং আপনি কলের পরিণতি বা পারামিটার পরীক্ষা করতে পারেন।
spyOn() এর ব্যবহার
spyOn() ফাংশনটি একটি মক ফাংশন বা মেথড তৈরি করতে ব্যবহৃত হয়। এটি প্রথম আর্গুমেন্ট হিসেবে একটি অবজেক্ট এবং দ্বিতীয় আর্গুমেন্ট হিসেবে একটি মেথডের নাম নেয়। এটি ওই মেথডের কাজের পরিবর্তে একটি স্পাই তৈরি করে, যা কলগুলোর আচরণ পরীক্ষা করতে সহায়তা করে।
উদাহরণ:
describe("Jasmine Mocks with spyOn", function() {
it("should mock a method and check the result", function() {
const obj = {
add: function(a, b) {
return a + b;
}
};
// স্পাই ব্যবহার করে add মেথড মক করা
spyOn(obj, 'add').and.returnValue(10);
// মক মেথড কল করা
const result = obj.add(3, 4);
// মক ফাংশনের রিটার্ন ভ্যালু পরীক্ষা করা
expect(result).toBe(10);
expect(obj.add).toHaveBeenCalled(); // চেক করুন যে মেথডটি কল হয়েছে
expect(obj.add).toHaveBeenCalledWith(3, 4); // চেক করুন যে সঠিক আর্গুমেন্টের সাথে কল হয়েছে
});
});
এখানে:
spyOn(obj, 'add'): এটিobj.add()মেথডের জন্য একটি স্পাই তৈরি করবে।and.returnValue(10): স্পাইটি যখন কল হবে, তখন এটি10রিটার্ন করবে, আসলaddফাংশনের কাজ করার পরিবর্তে।expect(obj.add).toHaveBeenCalled(): এটি পরীক্ষা করবে যে মেথডটি কল হয়েছে কিনা।expect(obj.add).toHaveBeenCalledWith(3, 4): এটি পরীক্ষা করবে যে সঠিক আর্গুমেন্ট দিয়ে মেথডটি কল হয়েছে কিনা।
and.callThrough(): আসল ফাংশন কল করা
যখন আপনি মক ফাংশন তৈরি করবেন, তখন আপনি চাইলে আসল ফাংশনটি চালিয়ে যেতে পারেন। এর জন্য and.callThrough() ব্যবহার করা হয়।
উদাহরণ:
describe("Jasmine Mocks with callThrough", function() {
it("should call the original function", function() {
const obj = {
multiply: function(a, b) {
return a * b;
}
};
spyOn(obj, 'multiply').and.callThrough(); // আসল ফাংশন চালাতে allow করবে
const result = obj.multiply(2, 5);
expect(result).toBe(10); // আসল ফাংশনের কাজ
expect(obj.multiply).toHaveBeenCalled(); // মেথডটি কল হয়েছে কিনা
});
});
এখানে:
and.callThrough()ব্যবহার করা হয়েছে যাতে মক ফাংশন সত্ত্বেও আসলmultiply()ফাংশনটি চালানো হয়।multiply(2, 5)কল করার পর, এর সঠিক ফলাফল10রিটার্ন হবে, যেহেতু আসল ফাংশন কল করা হয়েছে।
and.callFake(): কাস্টম ফাংশন ব্যবহার করা
and.callFake() ব্যবহার করে আপনি একটি কাস্টম ফাংশন প্রদান করতে পারেন, যা স্পাইয়ের কল হলে চলবে। এটি আসল ফাংশনের পরিবর্তে আপনার নিজস্ব ফাংশনটিকে চালানোর সুযোগ দেয়।
উদাহরণ:
describe("Jasmine Mocks with callFake", function() {
it("should call a fake function", function() {
const obj = {
subtract: function(a, b) {
return a - b;
}
};
spyOn(obj, 'subtract').and.callFake(function(a, b) {
return a + b; // কাস্টম লজিক (আসল লজিকের পরিবর্তে)
});
const result = obj.subtract(7, 3);
expect(result).toBe(10); // কাস্টম ফাংশনের রিটার্ন ভ্যালু
expect(obj.subtract).toHaveBeenCalled(); // মেথডটি কল হয়েছে কিনা
expect(obj.subtract).toHaveBeenCalledWith(7, 3); // সঠিক আর্গুমেন্টের সাথে কল হয়েছে
});
});
এখানে:
and.callFake()ব্যবহার করে একটি কাস্টম ফাংশন প্রদান করা হয়েছে, যেটি আসলsubtract()ফাংশনের পরিবর্তে কল হবে। এতে আসল গাণিতিক অপারেশন পরিবর্তে আমরাa + bরিটার্ন করছি।expect()দিয়ে আমরা চেক করেছি যে মেথডটি সঠিকভাবে কল হয়েছে এবং সঠিক আর্গুমেন্ট ব্যবহার করা হয়েছে।
and.stub(): মেথডকে মক করে ফেলা
and.stub() ব্যবহার করে আপনি মেথডকে পুরোপুরি মক করে ফেলতে পারেন, যাতে মেথডের কোনো আচরণ না থাকে। এটি ফাংশনের আচরণ নিয়ন্ত্রণে রাখা হয়।
উদাহরণ:
describe("Jasmine Mocks with stub", function() {
it("should not call the original function", function() {
const obj = {
greet: function(name) {
return "Hello, " + name;
}
};
spyOn(obj, 'greet').and.stub(); // greet মেথডকে মক করে ফেলেছে
const result = obj.greet("John");
expect(result).toBeUndefined(); // মক ফাংশন রিটার্ন কিছুই করবে না
expect(obj.greet).toHaveBeenCalled(); // মেথডটি কল হয়েছে কিনা
});
});
এখানে:
and.stub()ব্যবহার করা হয়েছে যাgreet()মেথডকে পুরোপুরি মক করে ফেলেছে, ফলে এটি কোনো রিটার্ন ভ্যালু প্রদান করবে না।expect(result).toBeUndefined()দ্বারা যাচাই করা হয়েছে যে, মক ফাংশন কোন রিটার্ন ভ্যালু দেয়নি।
সারাংশ
JasmineJS এ মক (Mocks) তৈরি করার মাধ্যমে আপনি আপনার টেস্টিং আরো নিয়ন্ত্রিত এবং নির্দিষ্ট ফাংশন বা মেথডের আচরণ পরীক্ষা করতে পারবেন। এর জন্য মূল পদ্ধতি হলো spyOn(), যা মেথডের কল রেকর্ড করে এবং তার আচরণ পরিবর্তন করতে সাহায্য করে। আপনি বিভিন্ন ফাংশনালিটি প্রয়োগ করতে পারেন:
and.returnValue(): মক ফাংশনের জন্য একটি নির্দিষ্ট রিটার্ন ভ্যালু প্রদান।and.callThrough(): আসল ফাংশন চালানোর অনুমতি।and.callFake(): কাস্টম ফাংশন প্রদান করা।and.stub(): মেথডের আচরণকে মক করে ফেলতে।
এইসব পদ্ধতি ব্যবহার করে আপনি JasmineJS এ খুবই কার্যকর এবং নির্ভরযোগ্য টেস্ট তৈরি করতে পারবেন।
JasmineJS এ Stubs এবং Mocks দুটি গুরুত্বপূর্ণ টেস্টিং কৌশল, যা আপনাকে নির্দিষ্ট ফাংশন বা মেথডের আচরণ মক বা নিয়ন্ত্রণ করতে সাহায্য করে। তবে এই দুটি কৌশলের মধ্যে কিছু মৌলিক পার্থক্য রয়েছে, যা তাদের ব্যবহার এবং উদ্দেশ্য আলাদা করে।
Stubs
Stub হল একটি টেস্টিং কৌশল, যা মূলত কোনো ফাংশনের আচরণ প্রতিস্থাপন করে এবং এটি নির্দিষ্ট মান বা ফলাফল প্রদান করে। এটি মূলত সেই ফাংশন বা মেথডের আউটপুটকে নিয়ন্ত্রণ করার জন্য ব্যবহৃত হয়, যাতে করে আপনি টেস্টের মধ্যে অন্যান্য নির্ভরতা এড়িয়ে কেবলমাত্র যে অংশ পরীক্ষা করছেন সেটিকে আলাদা করতে পারেন।
Stub এর বৈশিষ্ট্য:
- নির্দিষ্ট ফলাফল প্রদান: Stub সাধারণত একটি নির্দিষ্ট মান বা ফলাফল ফেরত দেয়। এটি মূল ফাংশনের আচরণ পরিবর্তন করে এবং টেস্টিং পরিবেশের জন্য এটি নির্ধারিত আউটপুট দেয়।
- কেবল আউটপুট নিয়ন্ত্রণ: Stub মূলত ফাংশনের আউটপুট নিয়ন্ত্রণ করে, কিন্তু এটি কোনো রেকর্ডিং বা কল হিস্টোরি রাখে না।
উদাহরণ:
describe("stub example", function() {
it("should return a fixed value", function() {
var myObject = {
getData: function() {
return 10; // Stubbed function returns a fixed value
}
};
spyOn(myObject, "getData").and.callFake(function() {
return 5; // The stubbed method now returns 5 instead of 10
});
expect(myObject.getData()).toBe(5); // Verifying the stubbed value
});
});
এখানে:
spyOn()ফাংশনটিgetDataমেথডটি স্পাই করার জন্য ব্যবহার করা হয়েছে, এবংcallFake()ব্যবহার করে এটি একটি স্টাব ফাংশনে রূপান্তরিত হয়েছে, যা ৫ ফেরত দেয়।- স্টাবটি
getData()মেথডের আউটপুট পরিবর্তন করে, কিন্তু কোন কল হিস্টোরি রাখে না।
Mocks
Mock হল একটি আরও উন্নত টেস্টিং কৌশল যা শুধু ফাংশনের আউটপুট নিয়ন্ত্রণ করেই শেষ হয় না, বরং এটি সেই ফাংশনটির কল হিস্টোরি এবং আচরণও রেকর্ড করে। মক ব্যবহার করে আপনি টেস্ট করতে পারেন যে কোনো ফাংশন বা মেথড কতবার কল হয়েছে, ঠিক কোন আর্গুমেন্টগুলো দিয়ে কল করা হয়েছে, এবং এর কল হওয়া উচিত কিনা।
Mock এর বৈশিষ্ট্য:
- ফাংশনের কল হিস্টোরি: Mock ফাংশনটি কল হওয়া বা না হওয়া, কতবার কল হয়েছে এবং এর আর্গুমেন্ট কী ছিল—এই সমস্ত তথ্য রেকর্ড করে।
- আউটপুট এবং আচরণ নিয়ন্ত্রণ: Mock কেবল আউটপুট নয়, ফাংশনের আচরণ এবং কল হিস্টোরিও নিয়ন্ত্রণ করে।
- অটোমেটিক ভ্যালিডেশন: মক সাধারণত স্বয়ংক্রিয়ভাবে যাচাই করে যে টেস্টের সময়ে ফাংশনটি কতবার এবং কিভাবে কল হয়েছে।
উদাহরণ:
describe("mock example", function() {
it("should track how many times a method is called", function() {
var myObject = {
processData: function(value) {
return value * 2;
}
};
spyOn(myObject, "processData").and.callFake(function(value) {
return value * 3; // Mock method returns value * 3
});
myObject.processData(5);
myObject.processData(10);
expect(myObject.processData).toHaveBeenCalled(); // Verifying that the mock method was called
expect(myObject.processData).toHaveBeenCalledTimes(2); // Verifying it was called twice
expect(myObject.processData).toHaveBeenCalledWith(5); // Verifying it was called with the argument 5
});
});
এখানে:
spyOn()ব্যবহার করা হয়েছেprocessDataমেথডটি মক করার জন্য এবংcallFake()দিয়ে মক ফাংশনটি তৈরি করা হয়েছে।toHaveBeenCalled()এবংtoHaveBeenCalledTimes()এর মাধ্যমে মক ফাংশনটির কল হিস্টোরি যাচাই করা হচ্ছে।toHaveBeenCalledWith()যাচাই করে যে ফাংশনটি নির্দিষ্ট আর্গুমেন্ট সহ কল হয়েছে।
Stubs এবং Mocks এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Stub | Mock |
|---|---|---|
| ফাংশন আচরণ | Stub শুধুমাত্র আউটপুট নিয়ন্ত্রণ করে। | Mock আউটপুট, কল হিস্টোরি, এবং আচরণ নিয়ন্ত্রণ করে। |
| কল হিস্টোরি | কল হিস্টোরি রেকর্ড করে না। | কল হিস্টোরি রেকর্ড করে, যেমন কতবার কল হয়েছে। |
| ব্যবহার | ফাংশনের আউটপুট পরীক্ষার জন্য ব্যবহৃত হয়। | ফাংশনটির কল এবং আচরণ পরীক্ষা করার জন্য ব্যবহৃত হয়। |
| টেস্ট ভ্যালিডেশন | ভ্যালিডেশন স্বতন্ত্রভাবে করতে হয়। | মকটি স্বয়ংক্রিয়ভাবে যাচাই করতে পারে যে ফাংশনটি কতবার কল হয়েছে। |
| প্রধান উদ্দেশ্য | নির্দিষ্ট আউটপুট নিয়ন্ত্রণ। | ফাংশনের আচরণ এবং কল হিস্টোরি পরীক্ষা। |
সারাংশ
- Stubs: এগুলি ফাংশনের আউটপুট নিয়ন্ত্রণ করে এবং টেস্টের মধ্যে নির্দিষ্ট ফলাফল প্রদান করে। এগুলোর মূল উদ্দেশ্য ফাংশনের আচরণকে সহজভাবে মক করা।
- Mocks: এগুলি শুধুমাত্র আউটপুট নয়, ফাংশনের কল হিস্টোরি, আর্গুমেন্ট, এবং কতবার কল হয়েছে এসব সমস্ত তথ্য রেকর্ড করে। এগুলি সাধারণত ফাংশনের আচরণ এবং কল হিস্টোরি পরীক্ষা করতে ব্যবহৃত হয়।
JasmineJS এ আপনি যেভাবে টেস্ট করছেন তার ওপর ভিত্তি করে এই দুটি কৌশল ব্যবহার করতে পারেন—যেখানে স্টাবটি আউটপুট নিয়ন্ত্রণে ব্যবহার হবে এবং মকটি কল হিস্টোরি এবং আচরণ যাচাই করার জন্য ব্যবহৃত হবে।
Dependency Injection (DI) একটি সফটওয়্যার ডিজাইন প্যাটার্ন যা ক্লাস বা ফাংশনগুলোর মধ্যে নির্ভরতাগুলো বাইরের উৎস থেকে ইনজেক্ট (প্রদান) করে। JasmineJS এ Dependency Injection ব্যবহার করে আপনি সহজেই মক (mock) বা স্পাই (spy) অবজেক্ট ইনজেক্ট করতে পারেন, যা আপনার টেস্টগুলিকে আরও বেশি ইউনিট টেস্টযোগ্য ও স্বাধীন করে তোলে।
DI এর মাধ্যমে আপনি টেস্টের জন্য নির্দিষ্ট উপাদানগুলো ইনজেক্ট করতে পারেন, যার ফলে নির্দিষ্ট ফাংশন বা ক্লাসের বাইরে থাকা ডিপেন্ডেন্সি গুলোর ওপর নিয়ন্ত্রণ সহজ হয়। এভাবে আপনি টেস্টের ভিতরে নির্ভরশীল অবজেক্টগুলোর আচরণ নিয়ন্ত্রণ করতে পারেন।
Dependency Injection এর মৌলিক ধারণা
Dependency Injection একটি ক্লাস বা ফাংশনের বাইরে থেকে তার নির্ভরশীল অবজেক্টগুলিকে সরবরাহ করা। এর মাধ্যমে কোডে যেসব নির্ভরতাগুলি থাকে (যেমন API কল, ডাটাবেস অ্যাক্সেস, থার্ড-পার্টি লাইব্রেরি ইত্যাদি), সেগুলিকে সহজেই টেস্টিং এর জন্য মক বা স্পাই অবজেক্টের মাধ্যমে প্রতিস্থাপন করা যায়।
JasmineJS এ Dependency Injection
JasmineJS এ DI প্রাকটিস প্রয়োগ করার জন্য, আমরা মূল ফাংশন বা ক্লাসের ডিপেন্ডেন্সিগুলিকে মক বা স্পাই অবজেক্ট দিয়ে রিপ্লেস (replace) করতে পারি। এতে করে আমরা মূল ফাংশনের আচরণ পরীক্ষা করতে পারি, এবং বাহ্যিক নির্ভরশীলতা (যেমন ডাটাবেস বা API কল) শূন্য বা মক করা যেতে পারে।
উদাহরণ: JasmineJS এ Dependency Injection
ধরা যাক, আমাদের একটি UserService ক্লাস আছে যা ডাটাবেসে ডেটা সেভ করতে একটি Database ক্লাসের ওপর নির্ভরশীল। এখানে, Database ক্লাসটিকে আমরা একটি মক (mock) অবজেক্ট দিয়ে রিপ্লেস করব এবং শুধু UserService এর কার্যকারিতা টেস্ট করব।
Code Example:
// মূল কোড (UserService.js)
class Database {
save(user) {
// এই মেথডটি ডাটাবেসে ইউজারের ডেটা সেভ করবে
console.log("User saved to database:", user);
}
}
class UserService {
constructor(db) {
this.db = db; // এখানে ডিপেন্ডেন্সি ইনজেক্ট করা হচ্ছে
}
createUser(name) {
const user = { name };
this.db.save(user); // ডিপেন্ডেন্সি ব্যবহার হচ্ছে
}
}
এখানে UserService ক্লাসটি Database ক্লাসের ওপর নির্ভরশীল, এবং Database মেথড save() কল করার জন্য নির্ভর করে।
JasmineJS টেস্টে Dependency Injection প্রয়োগ
এখন, আমরা JasmineJS ব্যবহার করে এই কোডের জন্য টেস্ট লিখব, যেখানে Database ক্লাসটিকে মক বা স্পাই অবজেক্ট দিয়ে রিপ্লেস করা হবে।
টেস্টের উদাহরণ:
describe("UserService", function() {
let userService;
let mockDatabase;
beforeEach(function() {
// Dependency Injection এর মাধ্যমে mockDatabase ইনজেক্ট করা হচ্ছে
mockDatabase = {
save: jasmine.createSpy("save") // মক মেথড তৈরি
};
userService = new UserService(mockDatabase); // UserService তৈরি হচ্ছে মক ডাটাবেসের সাথে
});
it("should call save on the database when creating a user", function() {
const userName = "John";
userService.createUser(userName);
// টেস্ট নিশ্চিত করবে যে save() মেথডটি কল হয়েছে
expect(mockDatabase.save).toHaveBeenCalledWith({ name: userName });
});
});
এখানে:
mockDatabase:Databaseক্লাসের মক অবজেক্ট তৈরি করা হয়েছে। এখানেsave()মেথডটি একটি স্পাই মেথড হিসেবে তৈরি করা হয়েছে, যা পরীক্ষায় এটি কতবার এবং কিভাবে কল হয়েছে তা ট্র্যাক করবে।userService:UserServiceক্লাসটিmockDatabaseইনজেক্ট করা হয়েছে, যার ফলে আসল ডাটাবেস কলটি না হয়ে মক অবজেক্টেরsave()মেথডটি কল হবে।toHaveBeenCalledWith(): এই Matcher টি যাচাই করবে যেsave()মেথডটি সঠিক আর্গুমেন্ট সহ কল হয়েছে কি না।
JasmineJS এ Dependency Injection এর সুবিধা
- ইউনিট টেস্টিং সহজ করা: ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করে আপনি বাহ্যিক নির্ভরতাগুলিকে মক বা স্পাই দিয়ে রিপ্লেস করতে পারেন, যার ফলে আপনার টেস্ট কেসগুলো খুবই স্বাধীন এবং দ্রুত চলে।
- বাহ্যিক অবজেক্টগুলোর ওপর নিয়ন্ত্রণ: মক অবজেক্ট বা স্পাই ইনজেক্ট করে আপনি বাহ্যিক অবজেক্টের আচরণ নিয়ন্ত্রণ করতে পারেন, যেমন API কল বা ডাটাবেস অ্যাক্সেস।
- আলাদা ফাংশনের টেস্ট: ডিপেন্ডেন্সি ইনজেকশনের মাধ্যমে আপনি একে অপরের থেকে স্বাধীনভাবে প্রতিটি ফাংশন বা ক্লাস টেস্ট করতে পারবেন।
- রিলায়েবল টেস্টিং: বাহ্যিক সিস্টেমের ওপর নির্ভরশীলতা কমানোর মাধ্যমে, আপনি নির্ভরযোগ্য টেস্ট ফলাফল পাবেন।
সারাংশ
- Dependency Injection: JasmineJS এ Dependency Injection এর মাধ্যমে আপনি মক বা স্পাই অবজেক্ট ব্যবহার করে বাহ্যিক নির্ভরতাগুলোকে ইনজেক্ট করতে পারেন। এর মাধ্যমে আপনার টেস্ট কেসগুলোকে আরও স্বাধীন এবং ইউনিট টেস্টযোগ্য করা সম্ভব হয়।
- Mocking এবং Spying: Dependency Injection ব্যবহার করে আপনি বাহ্যিক ফাংশন বা ক্লাসের আচরণ মক (mock) বা স্পাই (spy) করতে পারেন, যা আপনার টেস্ট কেসগুলির ওপর নিয়ন্ত্রণ নিয়ে আসে।
- প্রধান সুবিধা: এর মাধ্যমে আপনি কোডের নির্ভরশীলতাগুলোকে ম্যানেজ করতে পারেন এবং আপনার টেস্টগুলোকে আরও নির্ভরযোগ্য ও কার্যকরী করতে পারেন।
Read more